package com.pigcloud.sop.gateway.filter;

import com.alibaba.cloud.commons.lang.StringUtils;
import com.pigcloud.sop.gatewaycommon.bean.SopConstants;
import com.pigcloud.sop.gatewaycommon.gateway.ServerWebExchangeUtil;
import com.pigcloud.sop.gatewaycommon.util.IpUtils;
import com.pigcloud.sop.gatewaycommon.util.MDCUtil;
import com.pigcloud.sop.gatewaycommon.util.RequestUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * @author zsx
 * @date 2023/12/1 15:44
 */
@Slf4j
@Configuration
public class TraceFilter implements GlobalFilter, Ordered {

    /**
     * Process the Web request and (optionally) delegate to the next {@code GatewayFilter}
     * through the given {@link GatewayFilterChain}.
     *
     * @param exchange the current server exchange
     * @param chain    provides a way to delegate to the next filter
     * @return {@code Mono<Void>} to indicate when request processing is complete
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //链路追踪id
        final String traceId = ServerWebExchangeUtil.getTraceIdIfNullNew(exchange);
        ServerWebExchange customExchange  = addHeader(exchange, MDCUtil.TRACE_ID, traceId);
        String url = exchange.getRequest().getURI().getPath();
        log.debug("请求的url:{}", url);
        String serverName = getFirstPart(url);
        log.debug("serverName:{}", serverName);
        if (StringUtils.isNotBlank(serverName)) {
            url = url.substring(serverName.length() + 1);
        }
        String clientIp = IpUtils.getIpAddress(exchange.getRequest());
        if(clientIp.equals("192.168.2.72")){
            customExchange= addHeader(customExchange, SopConstants.CLIENT_IP,clientIp);
        }
        String finalUrl = url;
        log.debug("最终的url:{}", finalUrl);
        Mono<Void> mono = chain.filter(customExchange ).then(Mono.fromRunnable(() -> {
            MDCUtil.removeAll();
            MDCUtil.putAll(traceId, serverName, clientIp, finalUrl);
        }));
        customExchange .getResponse().getHeaders().add(MDCUtil.TRACE_ID, traceId);
        return mono;
    }

    /**
     * Get the order value of this object.
     * <p>Higher values are interpreted as lower priority. As a consequence,
     * the object with the lowest value has the highest priority (somewhat
     * analogous to Servlet {@code load-on-startup} values).
     * <p>Same order values will result in arbitrary sort positions for the
     * affected objects.
     *
     * @return the order value
     * @see #HIGHEST_PRECEDENCE
     * @see #LOWEST_PRECEDENCE
     */
    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE;
    }


    private ServerWebExchange addHeader(ServerWebExchange exchange, String key, String value) {
        ServerHttpRequest request = exchange.getRequest().mutate()
                .header(key, new String[]{value})
                .build();
        return exchange.mutate().request(request).build();
    }

    private String getFirstPart(String url) {
        String[] arr = url.split("/");
        return arr.length > 1 ? arr[1] : "";
    }
}
